using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Core;

namespace SupportGenerator
{
	public class ParameterNamesGenerator
	{
		private string filterPropertiesValue;
		private string propertiesValue;
		private const string DAO_SUPPORT_DIRECTORY = @"GeneratedFiles\Support\Request\";

		private const string ITEM_TEMPLATE = @"			public const string {PROPERTY} = ""{PROPERTY_STRING}"";";
		private const string FILTER_ITEM_TEMPLATE = @"				public const string {PROPERTY} = ""filter_{PROPERTY_STRING}"";";

		private const string NESTED_CLASS_TEMPLATE =
			@"		#region Nested type: {CLASS_NAME}

		public class {CLASS_NAME}
		{
			#region Nested type: Field

			public class Field
			{
{ITEMS}
			}
			
			#endregion			

			#region Nested type: Filter

			public class Filter
			{
{FILTER_ITEMS}
			}

			#endregion
		}

		#endregion";

		private const string PARAMETER_NAMES_CLASS_WRAPPER =
			@"namespace {NAMESPACE}
{
	public class ParameterNames
	{
	
{NESTED_CLASSES}

	}
}";


		public ParameterNamesGenerator() {}


		public ParameterNamesGenerator(Assembly assembly)
		{
			this.Assembly = assembly;
		}

		public Assembly Assembly { get; set; }

		public void Execute(IEnumerable<string> selectedClassNames)
		{
			string nestedClasses = "";

			string nameSpace = "";

			foreach (string fullName in selectedClassNames) {
				//create a new template string
				string singleClass = NESTED_CLASS_TEMPLATE;

				Type classType = this.Assembly.GetType(fullName);
				string className = classType.Name;

				nameSpace = Utilities.GetSupportRequestNameSpace(classType.Namespace);

				this.GetPropertiesForClass(classType);

				singleClass = singleClass.Replace("{CLASS_NAME}", className);

				singleClass = singleClass.Replace("{ITEMS}", this.propertiesValue);

				singleClass = singleClass.Replace("{FILTER_ITEMS}", this.filterPropertiesValue);

				nestedClasses += singleClass + Environment.NewLine + Environment.NewLine;
			}

			string classFile = PARAMETER_NAMES_CLASS_WRAPPER.Replace("{NESTED_CLASSES}", nestedClasses);

			classFile = classFile.Replace("{NAMESPACE}", nameSpace);

			Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + DAO_SUPPORT_DIRECTORY);

			TextWriter writer =
				new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + DAO_SUPPORT_DIRECTORY + "ParameterNames.cs");

			writer.Write(classFile);

			writer.Flush();
			writer.Close();
		}


		private void GetPropertiesForClass(Type type)
		{
			this.propertiesValue = "";
			this.filterPropertiesValue = "";

			foreach (MemberInfo member in type.GetMembers()) {
				if (member.MemberType == MemberTypes.Property) {
					if (member.Name != "Version") {
						this.propertiesValue += this.GetOneProperty(member.Name.ToUpper(), type.Name.ToLower() + "_" + member.Name.ToLower()) + Environment.NewLine
						                   + Environment.NewLine;
						this.filterPropertiesValue += this.GetOneFilterProperty(member.Name.ToUpper(), type.Name.ToLower() + "_" + member.Name.ToLower()) + Environment.NewLine
										   + Environment.NewLine;
					}
				}
			}
		}

		private string GetOneFilterProperty(
					string name,
					string value)
		{
			string property = FILTER_ITEM_TEMPLATE;

			property = property.Replace("{PROPERTY}", name);

			property = property.Replace("{PROPERTY_STRING}", value);

			return property;
		}

		private string GetOneProperty(
			string name,
			string value)
		{
			string property = ITEM_TEMPLATE;

			property = property.Replace("{PROPERTY}", name);

			property = property.Replace("{PROPERTY_STRING}", value);

			return property;
		}
	}
}